package com.cyf.plc.viewmodel

import androidx.lifecycle.*
import com.cyf.plc.bean.*
import com.cyf.plc.constant.Constants.Companion.ATTR_HUMIDITY
import com.cyf.plc.constant.Constants.Companion.ATTR_POWER
import com.cyf.plc.constant.Constants.Companion.ATTR_SET_TEMP
import com.cyf.plc.constant.Constants.Companion.ATTR_TEMP
import com.cyf.plc.constant.Constants.Companion.PANEL_ATTR_IDS
import com.cyf.plc.constant.Constants.Companion.UNDERLINE
import com.cyf.plc.constant.Constants.Companion.VW
import com.cyf.plc.data.repository.DatabaseRepository
import com.cyf.plc.data.repository.NetRepository
import com.cyf.plc.model.*
import com.cyf.plc.util.State
import com.squareup.moshi.Moshi
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.flowOn
import org.greenrobot.eventbus.EventBus
import java.util.ArrayList
import javax.inject.Inject

@ExperimentalCoroutinesApi
class MainViewModel @Inject constructor(
    private val netRepository: NetRepository,
    private val databaseRepository: DatabaseRepository,
    private val moshi: Moshi
) : ViewModel() {

    fun saveFloors(plcFloors: List<PlcFloor>) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                databaseRepository.saveFloors(plcFloors)
            }
        }
    }

    fun saveRooms(plcRooms: List<PlcRoom>) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                databaseRepository.saveRooms(plcRooms)
            }
        }
    }

    fun getPlcAttributes(attributeIds: Array<String>) =
        databaseRepository.getPlcAttributes(attributeIds).flowOn(Dispatchers.IO).asLiveData()

    fun getPlcSubAttributes(attributeIds: Array<String>) =
        databaseRepository.getPlcSubAttributes(attributeIds).flowOn(Dispatchers.IO).asLiveData()

    fun getPlcAttributes() =
        databaseRepository.getPlcAttributes().flowOn(Dispatchers.IO).asLiveData()

    fun savePlcAttributes(plcAttributes: List<PlcAttribute>) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                databaseRepository.savePlcAttributes(plcAttributes)
            }
        }
    }

    fun savePlcSubAttributes(plcSubAttributes: List<PlcSubAttribute>) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                databaseRepository.savePlcSubAttributes(plcSubAttributes)
            }
        }
    }

    fun saveYunConfigs(data: FloorRoomResponse) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                if (data.code == 0) {
                    val plcRooms = ArrayList<PlcRoom>()
                    val plcFloors = ArrayList<PlcFloor>()
                    val plcAttrs = ArrayList<PlcAttribute>()
                    val dataBeanList = data.data
                    if (dataBeanList != null) {
                        for (dataBean in dataBeanList) {
                            val pos = dataBeanList.indexOf(dataBean)
                            val floorId = pos + 1
                            val floorName = dataBean.floor
                            plcFloors.add(PlcFloor(floorId, floorName))
                            for (roomBean in dataBean.floorRoomList!!) {
                                val roomId = roomBean.type?.toInt()
                                val plcRoom = PlcRoom(roomId, roomBean.room, floorId.toLong())
                                plcRooms.add(plcRoom)
                                //新增面板属性
                                if (roomId != null) {
                                    plcAttrs.add(
                                        PlcAttribute(
                                            roomId.toString() + UNDERLINE + PANEL_ATTR_IDS[0],
                                            146 + 24 * (roomId - 1),
                                            VW,
                                            ATTR_POWER,
                                            "开关"
                                        )
                                    )
                                }
                                if (roomId != null) {
                                    plcAttrs.add(
                                        PlcAttribute(
                                            roomId.toString() + UNDERLINE + PANEL_ATTR_IDS[1],
                                            132 + 24 * (roomId - 1),
                                            VW,
                                            ATTR_TEMP,
                                            "温度"
                                        )
                                    )
                                }
                                if (roomId != null) {
                                    plcAttrs.add(
                                        PlcAttribute(
                                            roomId.toString() + UNDERLINE + PANEL_ATTR_IDS[2],
                                            148 + 24 * (roomId - 1),
                                            VW,
                                            ATTR_SET_TEMP,
                                            "设定温度"
                                        )
                                    )
                                }
                                if (roomId != null) {
                                    plcAttrs.add(
                                        PlcAttribute(
                                            roomId.toString() + UNDERLINE + PANEL_ATTR_IDS[3],
                                            136 + 24 * (roomId - 1),
                                            VW,
                                            ATTR_HUMIDITY,
                                            "湿度"
                                        )
                                    )
                                }
                            }
                        }
                    }
                    databaseRepository.deleteAll()
                    databaseRepository.saveFloors(plcFloors)
                    databaseRepository.saveRooms(plcRooms)
                    databaseRepository.savePlcAttributes(plcAttrs)
                }
            }
        }
    }

    fun getCity() = netRepository.getCity().asLiveData()

    fun getAllPlcFaultAddress() =
        databaseRepository.getAllPlcFaults().flowOn(Dispatchers.IO).asLiveData()

    fun getWeather(city: String?, viewLifecycleOwner: LifecycleOwner) {
        val cityBean = CityBean(city)
        viewModelScope.launch {
            while (true) {
                netRepository.getWeather(cityBean).asLiveData()
                    .observe(viewLifecycleOwner, Observer { state ->
                        when (state) {
                            is State.Success -> {
                                //处理天气信息
                                val weather = state.data.data?.weather
                                val air = state.data.data?.air
                                if (weather != null && air != null) {
                                    val outAirStatus = OutAirStatus("--", "--", "--")
                                    val weatherBean =
                                        moshi.adapter(WeatherBean::class.java).fromJson(weather)
                                    val airBean =
                                        moshi.adapter(AirBean::class.java).fromJson(air)

                                    outAirStatus.humidity = weatherBean?.now?.hum
                                    outAirStatus.temp = weatherBean?.now?.tmp
                                    outAirStatus.pm25 = airBean?.qlty

                                    println("获取到天气:$outAirStatus")
                                    EventBus.getDefault().post(outAirStatus)
                                }
                            }
                        }
                    })
                delay(1000 * 60 * 30)
            }
        }
    }

    fun savePlcFaults(plcFaults: ArrayList<PlcFault>) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                databaseRepository.savePlcFaults(plcFaults)
            }
        }
    }

    fun requestYunConfig(deviceId: String) = netRepository.getYunConfig(deviceId).asLiveData()

}